#ifndef WIDGET_H
#define WIDGET_H

#include "server.h"   // ★ 要在用 SimpleServer 之前包含
#include "mqtt.h"     // ★ 要在用 mqtt 之前包含
#include <QWidget>
#include <QEvent>
#include <QtCharts/QChartView>
#include <QtCharts/QLineSeries>
#include <QtCharts/QValueAxis>
#include <QTimer>
#include <QVector>
#include <QMutex>
#include <algorithm>
#include "fsmp_board/fsmpCamera.h"
#include <QLabel>
#include <QTextEdit>
#include <QPushButton>
#include "weatherclient.h"
#include <QProcess>


// 大模块：用渐变标题栏
#define MAKE_GRAD(parent, name, title) \
    makePane(parent, name, title, QColor("#090734"), QColor("#2c3e50"), 26, 240, 16, \
             "qlineargradient(spread:reflect, x1:0, y1:1, x2:1, y2:0, " \
             "stop:0 rgba(51, 190, 216, 255), stop:1 rgba(0, 1, 94, 255))")

// 小模块：用纯色标题栏
#define MAKE_PLAIN(parent, name, title) \
    makePane(parent, name, title, QColor("#090734"), QColor("#090734"), 28, 240, 12)

#define INTERVAL 500
#define RANGE 10
#define VIDEO "video1"



QT_CHARTS_USE_NAMESPACE

QT_BEGIN_NAMESPACE
namespace Ui { class Widget; }
QT_END_NAMESPACE

QT_CHARTS_USE_NAMESPACE

class Widget : public QWidget
{
    Q_OBJECT

public:
    Widget(QWidget *parent = nullptr);
    ~Widget();

    // 初始化各个大模块
    void InitWidget(QWidget *parent = nullptr);
    void InitW1(QWidget *parent = nullptr);
    void InitW2(QWidget *parent = nullptr);
    void InitW3(QWidget *parent = nullptr);
    void InitW4(QWidget *parent = nullptr);
    void InitW5(QWidget *parent = nullptr);
    void InitW6(QWidget *parent = nullptr);
    void InitW7(QWidget *parent = nullptr);
    void InitW8(QWidget *parent = nullptr);
    void InitW9(QWidget *parent = nullptr);
    void co9(QWidget *parent = nullptr);

    // 事件过滤器
    bool eventFilter(QObject* watched, QEvent* event) override;

    // 点击小模块时的处理（统一入口）
    void handlePaneClicked(const QString& title);

    // 初始化折线图（惰性初始化，只做一次；不会清空）
    void chart_init(QWidget *parent = nullptr);

    // w3 区域点击处理
    void w3ClickedHandler(const QString& title);

    void updatePlotArea();

    void onCamFrame(const QImage& img);

    //报警信息
    void DataWarning(const QString& Name,double data);

    void showThresholdDialog();

    void startRtmpPush();
    void stopRtmpPush();
    void setW4Status(const QString& text);

protected:
//    void resizeEvent(QResizeEvent *e) override;

public slots:
    // 外部实时数据入口（比如网络/串口线程发过来）
    // 建议用信号连接这个槽（QueuedConnection），避免跨线程直接加锁调用
    void updateSensors(double lightLux, double soilTempC, double soilHumPct, double coPpm);

private slots:
    // 定时器回调：统一推进四条曲线
public slots:
    void onSensorData(int hum, int temp, int light, int co);

private:
    Ui::Widget *ui;

    QWidget*    m_w3     = nullptr;

    QChart*     chart    = nullptr;
    QChartView* view     = nullptr;

    // 保留你原来的成员
    QLineSeries *line    = nullptr;        // 已不再使用这条单线，但不删你的成员
    QValueAxis  *axis_x  = nullptr;        // X 轴（点序号）
    QValueAxis  *axis_y  = nullptr;        // Y 轴（当前显示）
    QTimer      *timer   = nullptr;
    int          xValue  = 0;

    // —— 新增：四条曲线，各自独立 —— //
    QLineSeries *seriesLight    = nullptr; // 光照
    QLineSeries *seriesSoilTemp = nullptr; // 土壤温度
    QLineSeries *seriesSoilHum  = nullptr; // 土壤湿度
    QLineSeries *seriesco      = nullptr; // CO₂

    // X 轴滑动窗口大小（只显示最近 window 个点）
    const int   window = 300;

    // 当前显示哪条
    enum class Metric { Light, SoilTemp, SoilHum, co };
    Metric currentMetric = Metric::Light;

    // —— 外部数据缓冲（onTimer 每次取最新值推进） —— //
    QMutex  m_dataMutex;
    double  m_lightLux  = 1500.0; // 光照
    double  m_tempC     = 24.0;   // 温度 ℃
    double  m_humPct    = 55.0;   // 湿度 %
    double  m_coPpm    = 420.0;  // CO₂ ppm


    // 若没有外部喂值，可以用模拟数据（平滑随机游走）占位
    bool    m_useSimData = true;

    QWidget*     m_w4 = nullptr;      // 保存 w4 面板（可选，不加也行）
    QLabel*      m_camView = nullptr; // 显示相机画面的控件
    fsmpCamera*  m_camera = nullptr;  // 摄像头线程

    QImage m_lastFrame;

    QTimer* w5Timer = nullptr;
    QLabel* w5Image = nullptr;
    int     w5Index = 0;
    QStringList w5Images;

    SimpleServer* m_server = nullptr;

    QPushButton *btnSettings;

    QTextEdit*     m_text = nullptr;
    QTimer*        m_timer = nullptr;
    WeatherClient* m_client = nullptr;

    QString m_cityLabel = QStringLiteral("成都");
    double  m_lat = 30.5728;
    double  m_lon = 104.0668;

    mqtt* m_mqtt = nullptr;
    const int   m_farmId = 2;      // 云端用的农场/设备 ID，自行按需配置

    void fetchOnce();  // 抓取一次成都天气
    // 指向天气客户端（便于修改地址后立即刷新）
    WeatherClient* m_weatherClient = nullptr;

    // AQI 的网络管理器（复用，避免重复创建）
    QNetworkAccessManager* m_aqiNet = nullptr;

    // —— RTMP 推流 —— //
    QProcess* m_streamProc = nullptr;       // gst-launch 进程
    QTimer*   m_streamRetry = nullptr;      // 失败重试（可选）
    QString   m_rtmpUrl  = QStringLiteral("rtmp://120.26.201.192/live/%1").arg(m_farmId);
    QString   m_videoDev = QStringLiteral("/dev/%1").arg(QString(VIDEO)); // 默认取 /dev/video1，如需改为 /dev/video3 自行修改
    QLabel*   m_w4Status = nullptr;         // w4 内的状态文本

    bool    hasProgram(const char* name);
    QString pickFfmpegH264Encoder();  // h264_v4l2m2m / h264_omx / libx264 三选一

    QString pickH264Encoder();              // 选择可用 H.264 编码器
    bool    hasGstElement(const char* name);// 检测某个 GStreamer 元素是否存在

    // 弹窗：修改天气地址
    void showWeatherLocationDialog();

    // 拉取 AQI（Open-Meteo）
    void fetchAQI(double lat, double lon);
    // 内部工具
    void ensureSeriesAndAxes(QWidget *parentForView);
    void selectMetric(Metric m);

    // 辅助函数：取面板主体（保留你的注释）
    static QWidget* paneBody(QWidget* pane);
    void showEditIntroDialog();

    // —— w7 设备状态的6个标签 —— //
    QLabel *m_devHeat=nullptr, *m_devCool=nullptr, *m_devVent=nullptr,
           *m_devHum=nullptr,  *m_devSky=nullptr,  *m_devLamp=nullptr;

    // 根据 6 位掩码更新 UI
    void updateDeviceStateUi(quint8 mask);
    // 将“100001”/“001010”/“63”之类转成 0..63 的掩码
    quint8 parseBitsToMask(const QString& bits) const;

    public slots:
        // 接收下位机发来的 6 位字符串（推荐）
        void onDeviceBits(const QString& bits);
        // 或者直接接收掩码（0..63）
        void onDeviceMask(quint8 mask);
};

#endif // WIDGET_H
